home *** CD-ROM | disk | FTP | other *** search
/ Nautilus 1992 July / Nautilus-3-8 / Nautilus-3-8.bin / Tools & Utilities / Techy Stuff / Source ƒ / ASM 2.0 ƒ / as.c next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  5.1 KB  |  225 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "as.h"
  4. #include "table.h"
  5. #include "lookup.h"
  6.  
  7. int     Line_num = 0;           /* current line number                  */
  8. char    *File_name = "";        /* current file name                    */
  9. int     Err_count = 0;          /* total number of errors               */
  10. char    Line[MAXBUF] = {0};     /* input line buffer                    */
  11. char    Label[MAXLAB] = {0};    /* label on current line                */
  12. char    Op[MAXOP] = {0};        /* opcode mnemonic on current line      */
  13. char    Ext = 'u';              /* optional size after mnemonic         */
  14. char    *Optr = 0;              /* pointer into current Operand field   */
  15. int     Size;                   /* bitmap form of Ext                   */
  16. int     Pc = 0;                 /* Program Counter                      */
  17. int     Old_pc = 0;             /* Program Counter at beginning         */
  18. int     Pass = 1;               /* Current pass #                       */
  19.  
  20. int     Lflag = 1;              /* listing flag 0=nolist, 1=list        */
  21. int     Debug = 0;              /* debug flag                           */
  22.  
  23. extern int E_total;
  24. int     Fwdsize = W;            /* default fwd ref size                 */
  25. extern int P_total;
  26.  
  27. /*
  28.  *      as ---  cross assembler main program
  29.  */
  30. main(argc,argv)
  31. int     argc;
  32. char    **argv;
  33. {
  34.     int     xargc;
  35.     char    **xargv;
  36.  
  37.     if(argc < 2){
  38.         printf("Usage: %s [files]\n",*argv);
  39.         exit(1);
  40.         }
  41.     Line[MAXBUF-1] = '\n';    /* guard against garbage input */
  42.     exprinit();    /* forward ref init */
  43.     localinit();    /* target machine specific init. */
  44.  
  45.     xargc = argc;
  46.     xargv = argv;
  47.     while( --xargc ){
  48.         xargv++;
  49.         if( **xargv == '-' )
  50.             doflag(*xargv);
  51.         else
  52.             make_pass(*xargv);
  53.         }
  54.     if( Err_count == 0 ){
  55.         Pass++;
  56.         Pc      = 0;
  57.         E_total = 0;
  58.         P_total = 0;
  59.         Lflag   = 1;
  60.         expreinit();
  61.         srecinit(OBJNAME);
  62.         while(--argc){
  63.             argv++;
  64.             if( **argv == '-' )
  65.                  ;
  66.             else
  67.                 make_pass(*argv);
  68.             }
  69.         srecend(0);        /* end of S-records */
  70.         }
  71. if(Debug&DUMP){
  72.     dump_regs();
  73.     dump_comp();
  74.     dump_mne();
  75.     }
  76.     exit(Err_count);
  77. }
  78.  
  79. /*
  80.  *      doflag --- process optional flag argument
  81.  */
  82. doflag(s)
  83. char *s;
  84. {
  85.     switch( *(s+1) ){
  86.     case 'x':       Debug = atoi(s+2); break;
  87.     case 'l':       Lflag = 1; break;
  88.     case 'f':       Fwdsize = L; break;
  89.     default:
  90.         serror("Unrecognized flag: -%s",s);
  91.     }
  92. }
  93.  
  94. /*
  95.  *      make_pass --- read source code lines and generate code
  96.  */
  97. make_pass(s)
  98. char *s;
  99. {
  100.     int     saveline = Line_num;
  101.     char    *savefile = File_name;
  102.     int     savelflag = Lflag;
  103.     FILE    *f;
  104.     FILE    *fopen();
  105.     extern int P_force;
  106.  
  107.     Line_num = 0;
  108.     File_name = s;
  109.  
  110.     if( (f = fopen(s,"r")) == NULL )
  111.         error("Can't find file");
  112.     else{
  113.         while( getaline(f) ){
  114.             P_force = 0;    /* No force unless bytes emitted */
  115.             if(parse_line())
  116.                 process();
  117.             if(Pass == 2 && Lflag)
  118.                 print_line();
  119.             P_total = 0;    /* reset byte count */
  120.             }
  121.         f_record();
  122.         fclose(f);
  123.         }
  124.     Line_num = saveline;
  125.     File_name = savefile;
  126.     Lflag = savelflag;
  127. }
  128.  
  129. /*
  130.  *      getaline --- collect (possibly continued) an input line
  131.  */
  132. getaline(f)
  133. FILE *f;
  134. {
  135.     char *fgets();
  136.     register char *p = Line;
  137.     int remaining = MAXBUF-2;       /* space left in Line */
  138.     int len;                        /* line length */
  139.  
  140.     while( fgets(p,remaining,f) != (char *)NULL ){
  141.         Line_num++;
  142.         if((len = strlen(p)-2)<=0)
  143.             return(1);      /* just an empty line */
  144.         p += len;
  145.         if( *p != '\\' )
  146.             return(1);      /* not a continuation */
  147.         remaining -= len+2;
  148.         if(remaining<3)
  149.             warn("Continuation too long");
  150.         }
  151.     return(0);
  152. }
  153.  
  154. /*
  155.  *      parse_line --- split input line into label, op and operand
  156.  */
  157. parse_line()
  158. {
  159.     register char *ptrfrm = Line;
  160.     register char *ptrto = Label;
  161.     register int mnelen;
  162.     char    *skip_white();
  163.  
  164.     if( *ptrfrm == '*' || *ptrfrm == '#' || *ptrfrm == '\n' )
  165.         return(0);      /* a comment line */
  166.  
  167.     while( !delim(*ptrfrm) )
  168.         *ptrto++ = *ptrfrm++;
  169.     if(*--ptrto != ':')ptrto++;     /* allow trailing : */
  170.     *ptrto = '\0';
  171.  
  172.     ptrfrm = skip_white(ptrfrm);
  173.  
  174.     ptrto = Op;
  175.     while( !delim(*ptrfrm) )
  176.         *ptrto++ = mapdn(*ptrfrm++);
  177.     *ptrto = '\0';
  178.  
  179.     Ext = 'u';              /* default extension */
  180.     if( (mnelen = strlen(Op))>2 && Op[mnelen-2]=='.'){
  181.         if( alpha(Op[mnelen-1]) ){
  182.             Ext = mapdn(Op[mnelen-1]);
  183.             Op[mnelen-2] = '\0';
  184.             }
  185.         }
  186.  
  187.     ptrfrm = skip_white(ptrfrm);
  188.     Optr = ptrfrm;
  189.  
  190. if(Debug&PARSE)printf("Parseline: <%s> <%s.%c> <%s",Label,Op,Ext,Optr);
  191.     return(1);
  192. }
  193.  
  194. /* convert ascii Ext on mnemonic to bit map form */
  195. int etos[] = {0, B, 0, D, 0, 0, 0, 0, 0, 0, 0, L, 0,
  196.           0, 0, P, 0, 0, S, 0, U, 0, W, X, 0, 0};
  197.  
  198. /*
  199.  *    process --- determine mnemonic class and act on it
  200.  */
  201. process()
  202. {
  203.     register struct mne  *m;
  204.     register struct tmpl *t;
  205.     struct mne *mne_look();
  206.     struct tmpl *tmpl_match();
  207.  
  208.     Old_pc = Pc;            /* setup `old' program counter */
  209.     Size = etos[Ext-'a'];   /* setup size from extension */
  210.  
  211.     if(*Op=='\0'){           /* no mnemonic */
  212.         if(*Label)
  213.             install(Label,Pc,SYM);
  214.         }
  215.     else if( (m = mne_look(Op))== NULL)
  216.         serror("Unrecognized Mnemonic: %s",Op);
  217.     else if( (t = tmpl_match(m->ptmpl,m->ntmpl))==NULL)
  218.         error("Bad size or wrong operand(s)");
  219.     else{
  220.         if( *Label && t->class != EQU && t->class != FEQU )
  221.             install(Label,Pc,SYM);
  222.         do_op(t->class,t->op,t->op2);
  223.         }
  224. }
  225.